home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / arc.zoo / arcadd.c < prev    next >
C/C++ Source or Header  |  1989-01-29  |  10KB  |  384 lines

  1. /*
  2.  * $Header: arcadd.c,v 1.10 88/11/16 17:43:25 hyc Exp $
  3.  */
  4.  
  5. /*
  6.  * ARC - Archive utility - ARCADD
  7.  * 
  8.  * Version 3.40, created on 06/18/86 at 13:10:18
  9.  * 
  10.  * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  11.  * 
  12.  * By:  Thom Henderson
  13.  * 
  14.  * Description: This file contains the routines used to add files to an archive.
  15.  * 
  16.  * Language: Computer Innovations Optimizing C86
  17.  */
  18. #include <stdio.h>
  19. #include "arc.h"
  20. #if    MTS
  21. #include <mts.h>
  22. #endif
  23.  
  24. static    int    addfile();
  25. char    *strcpy();
  26. #ifdef __STDC__
  27. int    readhdr();
  28. #else
  29. int    strcmp(), strlen(), free(), readhdr(), unlink();
  30. #endif
  31. #if    UNIX
  32. int    izadir();
  33. #endif
  34. void    writehdr(), filecopy(), getstamp();
  35. void    pack(), closearc(), openarc(), abort();
  36.  
  37. void
  38. addarc(num, arg, move, update, fresh)        /* add files to archive */
  39.     int             num;    /* number of arguments */
  40.     char           *arg[];    /* pointers to arguments */
  41. int             move;        /* true if moving file */
  42. int             update;        /* true if updating */
  43. int             fresh;        /* true if freshening */
  44. {
  45.     char           *d, *dir();    /* directory junk */
  46.     char            buf[STRLEN];    /* pathname buffer */
  47.     char          **path;    /* pointer to pointers to paths */
  48.     char          **name;    /* pointer to pointers to names */
  49.     int             nfiles = 0;    /* number of files in lists */
  50.     int             notemp;    /* true until a template works */
  51.     int             nowork = 1;    /* true until files are added */
  52.     char           *i, *rindex();    /* string indexing junk */
  53. #ifndef __STDC__
  54.     char           *malloc(), *realloc();    /* memory allocators */
  55. #endif
  56.     int             n;    /* index */
  57. #if    MSDOS
  58.     unsigned int    coreleft();    /* remaining memory reporter */
  59. #endif
  60.     int        addbunch();
  61.  
  62.     if (num < 1) {        /* if no files named */
  63.         num = 1;    /* then fake one */
  64. #if    DOS
  65.         arg[0] = "*.*";    /* add everything */
  66. #endif
  67. #if    UNIX
  68.         arg[0] = "*";
  69. #endif
  70. #if    MTS
  71.         arg[0] = "?";
  72. #endif
  73.     }
  74.     path = (char **) malloc(sizeof(char **));
  75.     name = (char **) malloc(sizeof(char **));
  76.  
  77.  
  78.     for (n = 0; n < num; n++) {    /* for each template supplied */
  79.         strcpy(buf, arg[n]);    /* get ready to fix path */
  80. #if    !MTS
  81.         if (!(i = rindex(buf, '\\')))
  82.             if (!(i = rindex(buf, '/')))
  83.                 if (!(i = rindex(buf, ':')))
  84.                     i = buf - 1;
  85. #else
  86.         if (!(i = rindex(buf, sepchr[0])))
  87.             if (buf[0] != tmpchr[0])
  88.                 i = buf - 1;
  89.             else
  90.                 i = buf;
  91. #endif
  92.         i++;        /* pointer to where name goes */
  93.  
  94.         notemp = 1;    /* reset files flag */
  95.         for (d = dir(arg[n]); d; d = dir((char *)NULL)) {
  96.             notemp = 0;    /* template is giving results */
  97.             nfiles++;    /* add each matching file */
  98.             path = (char **) realloc(path, nfiles * sizeof(char **));
  99.             name = (char **) realloc(name, nfiles * sizeof(char **));
  100.             strcpy(i, d);    /* put name in path */
  101.             path[nfiles - 1] = malloc(strlen(buf) + 1);
  102.             strcpy(path[nfiles - 1], buf);
  103.             name[nfiles - 1] = d;    /* save name */
  104. #if    MSDOS
  105.             if (coreleft() < 5120) {
  106.                 nfiles = addbunch(nfiles, path, name, move, update, fresh);
  107.                 nowork = nowork && !nfiles;
  108.                 while (nfiles) {
  109.                     free(path[--nfiles]);
  110.                     free(name[nfiles]);
  111.                 }
  112.                 free(path);
  113.                 free(name);
  114.                 path = name = NULL;
  115.             }
  116. #endif
  117.         }
  118.         if (notemp && warn)
  119.             printf("No files match: %s\n", arg[n]);
  120.     }
  121.  
  122.     if (nfiles) {
  123.         nfiles = addbunch(nfiles, path, name, move, update, fresh);
  124.         nowork = nowork && !nfiles;
  125.         while (nfiles) {
  126.             free(path[--nfiles]);
  127.             free(name[nfiles]);
  128.         }
  129.         free(path);
  130.         free(name);
  131.     }
  132.     if (nowork && warn)
  133.         printf("No files were added.\n");
  134. }
  135.  
  136. int
  137. addbunch(nfiles, path, name, move, update, fresh)    /* add a bunch of files */
  138.     int             nfiles;    /* number of files to add */
  139.     char          **path;    /* pointers to pathnames */
  140.     char          **name;    /* pointers to filenames */
  141.     int             move;    /* true if moving file */
  142.     int             update;    /* true if updating */
  143.     int             fresh;    /* true if freshening */
  144. {
  145.     int             m, n;    /* indices */
  146.     char           *d;    /* swap pointer */
  147.     struct heads    hdr;    /* file header data storage */
  148.  
  149.     for (n = 0; n < nfiles - 1; n++) {    /* sort the list of names */
  150.         for (m = n + 1; m < nfiles; m++) {
  151.             if (strcmp(name[n], name[m]) > 0) {
  152.                 d = path[n];
  153.                 path[n] = path[m];
  154.                 path[m] = d;
  155.                 d = name[n];
  156.                 name[n] = name[m];
  157.                 name[m] = d;
  158.             }
  159.         }
  160.     }
  161.  
  162.     for (n = 0; n < nfiles - 1;) {    /* consolidate the list of names */
  163.         if (!strcmp(path[n], path[n + 1])    /* if duplicate names */
  164.             ||!strcmp(path[n], arcname)    /* or this archive */
  165. #if    UNIX
  166.             ||izadir(path[n])    /* or a directory */
  167. #endif
  168.             ||!strcmp(path[n], newname)    /* or the new version */
  169.             ||!strcmp(path[n], bakname)) {    /* or its backup */
  170.             free(path[n]);    /* then forget the file */
  171.             free(name[n]);
  172.             for (m = n; m < nfiles - 1; m++) {
  173.                 path[m] = path[m + 1];
  174.                 name[m] = name[m + 1];
  175.             }
  176.             nfiles--;
  177.         } else
  178.             n++;    /* else test the next one */
  179.     }
  180.  
  181.     if (!strcmp(path[n], arcname)    /* special check for last file */
  182.         ||!strcmp(path[n], newname)    /* courtesy of Rick Moore */
  183. #if    UNIX
  184.         ||izadir(path[n])
  185. #endif
  186.         || !strcmp(path[n], bakname)) {
  187.         free(path[n]);
  188.         free(name[n]);
  189.         nfiles--;
  190.     }
  191.     if (!nfiles)        /* make sure we got some */
  192.         return 0;
  193.  
  194.     for (n = 0; n < nfiles - 1; n++) {    /* watch out for duplicate
  195.                          * names */
  196.         if (!strcmp(name[n], name[n + 1]))
  197.             abort("Duplicate filenames:\n  %s\n  %s", path[n], path[n + 1]);
  198.     }
  199.     openarc(1);        /* open archive for changes */
  200.  
  201.     for (n = 0; n < nfiles;) { /* add each file in the list */
  202.         if (addfile(path[n], name[n], update, fresh) < 0) {
  203.             free(path[n]);        /* remove this name if */
  204.             free(name[n]);        /* it wasn't added */
  205.             for (m = n; m < nfiles-1 ; m++) {
  206.                 path[m] = path[m+1];
  207.                 name[m] = name[m+1];
  208.             }
  209.             nfiles--;
  210.         } else n++;
  211.     }
  212.  
  213.     /* now we must copy over all files that follow our additions */
  214.  
  215.     while (readhdr(&hdr, arc)) {    /* while more entries to copy */
  216.         writehdr(&hdr, new);
  217.         filecopy(arc, new, hdr.size);
  218.     }
  219.     hdrver = 0;        /* archive EOF type */
  220.     writehdr(&hdr, new);    /* write out our end marker */
  221.     closearc(1);        /* close archive after changes */
  222.  
  223.     if (move) {        /* if this was a move */
  224.         for (n = 0; n < nfiles; n++) {    /* then delete each file
  225.                          * added */
  226.             if (unlink(path[n]) && warn) {
  227.                 printf("Cannot unsave %s\n", path[n]);
  228.                 nerrs++;
  229.             }
  230.         }
  231.     }
  232.     return nfiles;        /* say how many were added */
  233. }
  234.  
  235. static          int
  236. addfile(path, name, update, fresh)    /* add named file to archive */
  237.     char           *path;    /* path name of file to add */
  238.     char           *name;    /* name of file to add */
  239.     int             update;    /* true if updating */
  240.     int             fresh;    /* true if freshening */
  241. {
  242.     struct heads    nhdr;    /* data regarding the new file */
  243.     struct heads    ohdr;    /* data regarding an old file */
  244.     FILE           *f;    /* file to add, opener */
  245. #ifndef __STDC__
  246.     FILE        *fopen();
  247. #endif
  248.     long            starts, ftell();    /* file locations */
  249.     int             upd = 0;/* true if replacing an entry */
  250.  
  251. #if    !MTS
  252.     if (!(f = fopen(path, OPEN_R)))
  253. #else
  254.     if (image)
  255.         f = fopen(path, "rb");
  256.     else
  257.         f = fopen(path, "r");
  258.     if (!f)
  259. #endif
  260.     {
  261.         if (warn) {
  262.             printf("Cannot read file: %s\n", path);
  263.             nerrs++;
  264.         }
  265.         return(-1);
  266.     }
  267. #if    !DOS
  268.     if (strlen(name) >= FNLEN) {
  269.         if (warn) {
  270.             char    buf[STRLEN];
  271.             printf("WARNING: File %s name too long!\n", name);
  272.             name[FNLEN-1]='\0';
  273.             while(1) {
  274.                 printf("  Truncate to %s (y/n)? ", name);
  275.                 fflush(stdout);
  276.                 fgets(buf, STRLEN, stdin);
  277.                 *buf = toupper(*buf);
  278.                 if (*buf == 'Y' || *buf == 'N')
  279.                     break;
  280.             }
  281.             if (*buf == 'N') {
  282.                 printf("Skipping...\n");
  283.                 fclose(f);
  284.                 return(-1);
  285.             }
  286.         }
  287.         else {
  288.             if (note)
  289.                 printf("Skipping file: %s - name too long.\n",
  290.                     name);
  291.             fclose(f);
  292.             return(-1);
  293.         }
  294.     }
  295. #endif
  296.     strcpy(nhdr.name, name);/* save name */
  297.     nhdr.size = 0;        /* clear out size storage */
  298.     nhdr.crc = 0;        /* clear out CRC check storage */
  299. #if    !MTS
  300.     getstamp(f, &nhdr.date, &nhdr.time);
  301. #else
  302.     {
  303.     char *buffer;
  304. #ifndef __STDC__
  305.     char *malloc();
  306. #endif
  307.     int    inlen;
  308.     struct    GDDSECT    *region;
  309.  
  310.     region=gdinfo(f->_fd._fdub);
  311.     inlen=region->GDINLEN;
  312.     buffer=malloc(inlen);    /* maximum line length */
  313.     setbuf(f,buffer);        
  314.     f->_bufsiz=inlen;        
  315.     f->_mods|=_NOIC;    /* Don't do "$continue with" */
  316.     f->_mo